package cn.craftyun.yunexam.controller;

import cn.craftyun.yunexam.entity.*;
import cn.craftyun.yunexam.request.ExamIdRequest;
import cn.craftyun.yunexam.request.SaveAnswerRequest;
import cn.craftyun.yunexam.service.*;
import cn.craftyun.yunexam.vo.ExamQuestionVO;
import cn.craftyun.yunexam.vo.ResultEntity;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.log4j.Log4j2;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.validation.Valid;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

/**
 * 考试控制器
 */
@Log4j2
@RestController
@RequestMapping("/exam")
public class ExamController {
    @Resource
    private ExamService examService;
    @Resource
    private ExamStatusService examStatusService;
    @Resource
    private UserService userService;
    @Resource
    private QuestionService questionService;
    @Resource
    private ExamAnswerService examAnswerService;
    @Resource
    private PaperService paperService;
    @Resource
    private ObjectMapper objectMapper;

    /**
     * 获取考试题目
     *
     * @param examIdRequest 考试ID对象
     * @return 返回结果实体类
     */
    @PostMapping("/getExamQuestion")
    public ResultEntity getExamQuestion(@RequestBody @Valid ExamIdRequest examIdRequest) {
        // 判断考试状态
        try {
            examStatusService.isExamGetOn(examIdRequest.getExamId(), userService.getLoginUser().getId());
        } catch (Exception e) {
            return ResultEntity.error(e.getMessage(), null);
        }
//        通过考试ID获取试卷ID
        Exam exam = examService.getById(examIdRequest.getExamId());
        // 通过试卷ID获取试卷
        Paper paper = paperService.getById(exam.getPaperId());
        // 通过试卷ID获取题目
        List<Question> paperQuestions = questionService.getPaperQuestions(exam.getPaperId());
        // 清除答案
        paperQuestions.forEach(question -> question.setAnswer(null));

        // 构造返回对象
        ExamQuestionVO examQuestionVO = new ExamQuestionVO();
        examQuestionVO.setPaperId(paper.getId());
        examQuestionVO.setName(paper.getName());
        examQuestionVO.setCaption(paper.getCaption());
        examQuestionVO.setQuestionList(paperQuestions);
        return ResultEntity.success("获取考试题目成功", examQuestionVO);
    }

    /**
     * 获取考试信息
     *
     * @param examIdRequest 考试ID对象
     * @return 返回结果实体类
     */
    @PostMapping("/getExam")
    public ResultEntity getExam(@RequestBody @Valid ExamIdRequest examIdRequest) {
        Exam exam = examService.getById(examIdRequest.getExamId());
        if (exam == null) {
            return ResultEntity.error("考试不存在", null);
        }
        return ResultEntity.success("获取考试信息成功", exam);
    }

    /**
     * 获取用户对于该考试的状态
     *
     * @param examIdRequest 考试ID对象
     * @return 返回结果实体类
     */
    @PostMapping("/getExamStatus")
    public ResultEntity getExamStatus(@RequestBody @Valid ExamIdRequest examIdRequest) {
        ExamStatus examStatus = examStatusService.getExamStatus(examIdRequest.getExamId(), userService.getLoginUser().getId());
        if (examStatus == null) {
            return ResultEntity.error("用户未参加考试", null);
        }
        return ResultEntity.success("获取考试状态成功", examStatus);
    }

    /**
     * 获得用户考试的最终成绩
     *
     * @param examIdRequest 考试ID 对象
     * @return 返回结果实体类
     */
    @PostMapping("/getExamScore")
    public ResultEntity getExamScore(@RequestBody @Valid ExamIdRequest examIdRequest) {
        // 判断考试状态
        ExamStatus examStatus = examStatusService.getExamStatus(examIdRequest.getExamId(), userService.getLoginUser().getId());
        if (examStatus == null) {
            return ResultEntity.error("您没有参加考试", null);
        }
        if (examStatus.getStatus() != 1) {
            return ResultEntity.error("考试进行中", null);
        }
        return ResultEntity.success("获取考试成绩成功", examStatus.getEndScore());
    }

    /**
     * 开始考试
     *
     * @param examIdRequest 考试ID对象
     * @return 返回结果实体类
     */
    @PostMapping("/startExam")
    public ResultEntity startExam(@RequestBody @Valid ExamIdRequest examIdRequest) {
        // 判断考试是否存在
        Exam exam = examService.getById(examIdRequest.getExamId());
        if (exam == null) {
            return ResultEntity.error("不存在该考试", null);
        }
        if (exam.getStartTime().getTime() > new Date().getTime()) {
            return ResultEntity.error("考试未开始", null);
        }
        // 判断用户是否参加考试
        ExamStatus examStatus = examStatusService.getExamStatus(examIdRequest.getExamId(), userService.getLoginUser().getId());
        if (examStatus != null) {
            return ResultEntity.error("用户已参加考试", null);
        }
        // 开始创建examStatus
        examStatus = new ExamStatus();
        examStatus.setUserId(userService.getLoginUser().getId());
        examStatus.setExamId(examIdRequest.getExamId());
        examStatus.setStatus(0);
        examStatus.setEndTime((int) (new Date().getTime() / 1000 + exam.getDuration()));
        examStatus.setEndScore(0);
        examStatusService.save(examStatus);
        return ResultEntity.success("开始考试成功", examStatus);
    }

    /**
     * 提交考试试卷
     *
     * @param examIdRequest 考试ID对象
     * @return 返回结果实体类
     */
    @PostMapping("/submitExam")
    public ResultEntity submitExam(@RequestBody @Valid ExamIdRequest examIdRequest) {
        // 判断考试状态
        ExamStatus examStatus = examStatusService.getExamStatus(examIdRequest.getExamId(), userService.getLoginUser().getId());
        if (examStatus == null) {
            return ResultEntity.error("您没有参加考试", null);
        }
        if (examStatus.getStatus() == 1) {
            return ResultEntity.error("您已提交试卷", null);
        }
        // 开始提交
        try {
            examStatusService.submitExam(examIdRequest.getExamId(), userService.getLoginUser().getId());
        } catch (Exception e) {
            return ResultEntity.error(e.getMessage(), null);
        }
        return ResultEntity.success("提交试卷成功", null);
    }

    /**
     * 保存当前题目的答案
     *
     * @param saveAnswerRequest 请求对象
     * @return 返回结果实体类
     */
    @PostMapping("/saveExamAnswer")
    public ResultEntity saveExamAnswer(@RequestBody @Valid SaveAnswerRequest saveAnswerRequest) throws JsonProcessingException {
        try {
            examStatusService.isExamGetOn(saveAnswerRequest.getExamId(), userService.getLoginUser().getId());
        } catch (Exception e) {
            return ResultEntity.error(e.getMessage(), null);
        }
        // 根据考试获取试卷ID
        Exam exam = examService.getById(saveAnswerRequest.getExamId());
        // 根据试卷ID找到提交的这道题目
        Wrapper<Question> getQuestionWrapper = new QueryWrapper<Question>()
                .eq("id", saveAnswerRequest.getQuestionId())
                .eq("paper_id", exam.getPaperId())
                .last("limit 1");
        Question question = questionService.getOne(getQuestionWrapper);
        if (question == null) {
            return ResultEntity.error("题目不存在", null);
        }
        // 开始保存答案
        ExamAnswer examAnswer = new ExamAnswer();
        examAnswer.setAnswer(objectMapper.writeValueAsString(saveAnswerRequest.getAnswer()));
        examAnswer.setUserId(userService.getLoginUser().getId());
        examAnswer.setExamId(saveAnswerRequest.getExamId());
        examAnswer.setQuestionId(saveAnswerRequest.getQuestionId());
        examAnswer.setAnswerScore(0);
        List<String> questionAnswer = objectMapper.readerForListOf(String.class).readValue(question.getAnswer());
        // 开始判题
        String a = Arrays.toString(saveAnswerRequest.getAnswer().stream().sorted().toArray());
        String b = Arrays.toString(questionAnswer.stream().sorted().toArray());
        if (a.equals(b)) {
            examAnswer.setAnswerScore(question.getScore());
        }
        Wrapper<ExamAnswer> getExamAnswerWrapper = new QueryWrapper<ExamAnswer>()
                .eq("user_id", userService.getLoginUser().getId())
                .eq("exam_id", saveAnswerRequest.getExamId())
                .eq("question_id", question.getId());
        examAnswerService.remove(getExamAnswerWrapper);
        if (examAnswerService.save(examAnswer)) {
            // 判题完成,返回保存成功
            return ResultEntity.success("答案保存成功", null);
        }
        return ResultEntity.error("答案保存失败，请重试", null);
    }

    /**
     * 恢复当前考试的答案
     *
     * @param examIdRequest 考试ID对象
     * @return 返回结果实体类
     */
    @PostMapping("/restoreAnswer")
    public ResultEntity restoreAnswer(@Valid @RequestBody ExamIdRequest examIdRequest) {
        // 恢复答案
        try {
            examStatusService.isExamGetOn(examIdRequest.getExamId(), userService.getLoginUser().getId());
        } catch (Exception e) {
            return ResultEntity.error(e.getMessage(), null);
        }
        List<ExamAnswer> examAnswer = examAnswerService.getExamAnswer(examIdRequest.getExamId(), userService.getLoginUser().getId());
        // 去掉里面成绩
        examAnswer.forEach(item -> item.setAnswerScore(null));
        return ResultEntity.success("获取成功", examAnswer);
    }

    @PostMapping("/getExamResult")
    public ResultEntity getExamResult(@Valid @RequestBody ExamIdRequest examIdRequest) {
        ExamStatus examStatus = examStatusService.getExamStatus(examIdRequest.getExamId(), userService.getLoginUser().getId());
        if (examStatus == null) {
            return ResultEntity.error("用户未参加考试", null);
        }
        if (examStatus.getStatus() != 1) {
            return ResultEntity.error("考试状态异常", null);
        }
        return ResultEntity.success("获取考试解析成功", examAnswerService.getUserResult(examStatus.getExamId(), userService.getLoginUser().getId()));
    }
}
